#region Using directives

/*
 * Copyright (c) 2005-2007 Alan Dean.
 * All rights reserved.
 */

using System;
using System.Collections.Generic;
using System.Globalization;

using ObjectThinking.Globalization;
using ObjectThinking.Xml.ResourceDescriptionFramework;

#endregion

namespace ObjectThinking
{
    public abstract class StringRule : RuleBase
    {
        // protected constructors

        protected StringRule()
        { }

        // protected methods

        protected bool Validate(ISelf obj, Uri key, string name)
        {
            return Validate(obj, key, name, true, 0, 0);
        }

        protected bool Validate(ISelf obj, Uri key, string name, bool required)
        {
            return Validate(obj, key, name, required, 0, 0);
        }

        protected bool Validate(ISelf obj, Uri key, string name, bool required, int minLength)
        {
            return Validate(obj, key, name, required, minLength, 0);
        }

        protected bool Validate(ISelf obj, Uri key, string name, bool required, int minLength, int maxLength)
        {
            if (obj == null) throw new ArgumentNullException();
            if (key == null) throw new ArgumentNullException();

            Rule.ClearViolations(this);

            if (required && (!obj.ContainsKey(key)))
            {
                this[key] = new ObjectRequiredViolation(name);
            }
            else
            {
                string value = obj[key].ToString();

                if (required && (value == null)) this[key] = new ObjectRequiredViolation(name);

                if (minLength == 0)
                {
                    if (value.Length == 0) this[key] = new StringEmptyViolation(name);
                }
                else if (value.Length < minLength + 1)
                {
                    this[key] = new StringMinLengthViolation(name, minLength);
                }

                if ((maxLength > 0) && (value.Length > maxLength))
                {
                    this[key] = new StringMaxLengthViolation(name, maxLength);
                }
            }

            return Rule.IsValid(this);
        }
    }
}